package com.slicktechnologies.shared.common.personlayer;
import static com.googlecode.objectify.ObjectifyService.ofy;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import com.google.gwt.core.shared.GwtIncompatible;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.OnSave;
import com.simplesoftwares.client.library.appstructure.search.Filter;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.helperconstants.FormTypes;
import com.simplesoftwares.rebind.annatonations.TableAnnotation;
import com.slicktechnologies.client.config.configurations.ConfigTypes;
import com.slicktechnologies.shared.MyUtility;
import com.slicktechnologies.shared.common.helperlayer.Address;
import com.slicktechnologies.shared.common.helperlayer.Config;
import com.slicktechnologies.shared.common.helperlayer.Contact;
import com.slicktechnologies.shared.common.helperlayer.DocumentUpload;
import com.slicktechnologies.shared.common.helperlayer.EducationalInfo;
import com.slicktechnologies.shared.common.helperlayer.PassportInformation;
import com.slicktechnologies.shared.common.helperlayer.PreviousCompanyHistory;
import com.slicktechnologies.shared.common.relationalLayer.BranchRelation;
import com.slicktechnologies.shared.common.relationalLayer.EmployeeRelation;

/**
 * Represents Employee of the Software's user company.
 */
@Entity
@Embed
public class Employee extends Person implements Serializable
{
	/***********************************************Entity Attributes*********************************/
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 7126833574273951975L;

	/** salary of the employee */
	protected double salary;
	/** joining date*/
	@Index
	protected Date joinedAt;
	/** Photo of Employee **/
	protected DocumentUpload photo;
	/** Employee Status */
	@Index
	protected boolean status;
	/** The branch name of employee*/
	@Index
	protected String branchName;
		/** The designation of employee  */
	@Index
     protected String designation;
    /** The Name of Role*/
	@Index
	protected String roleName;

	/** The ID Card Number*/
	@Index
	protected String idCardNo;
	/** The Acess Card Number*/
	@Index
	protected String accessCardNo;
	/** Passport Number*/
	@Index
	protected String departMent;
	/** name of employee to whom this employee reports **/
	@Index
	protected String reportsTo;
	
	/** Array List of Leave Approvers **/
	protected  ArrayList<String>approvers;
	
	/** Array List of Previous Work History **/
	protected ArrayList<PreviousCompanyHistory>previousCompanyHistory;
	/** Array List of Educational Information **/
	protected ArrayList<EducationalInfo>educationalInfo;
	
	/** Passport Information **/
	protected PassportInformation information;
	
	/**Type of Employee **/
	@Index
	protected String employeeType;
	
	protected String employeeBankAccountNo;
	
	protected String employeeBankName;
	
	protected String employeeESICcode;
	
	protected String employeePanNo;
	
	
	
	protected String ifscCode;
	
	protected String bankBranch;
	
	protected String accountNo;
	
	protected String ppfNo;
	protected String bloodGroup;
	
	
	
	
	

	public String getEmployeeBankAccountNo() {
		return employeeBankAccountNo;
	}


	public void setEmployeeBankAccountNo(String employeeBankAccountNo) {
		this.employeeBankAccountNo = employeeBankAccountNo;
	}


	public String getEmployeeBankName() {
		return employeeBankName;
	}

	/**Country of Employee **/
	@Index
	protected String country;
	



	public void setEmployeeBankName(String employeeBankName) {
		this.employeeBankName = employeeBankName;
	}


	public String getEmployeeESICcode() {
		return employeeESICcode;
	}


	public void setEmployeeESICcode(String employeeESICcode) {
		this.employeeESICcode = employeeESICcode;
	}


	public String getEmployeePanNo() {
		return employeePanNo;
	}


	public void setEmployeePanNo(String employeePanNo) {
		this.employeePanNo = employeePanNo;
	}
	
	
	
	

/***********************************************Relational Attributes****************************************/
	
	protected Key<Config>keyRole;
	protected Key<Config>keyDesignation;
	protected Key<BranchRelation>keyBranchName;
/***********************************************Join Kind Attribute******************************************/
	@Ignore
	protected boolean nameChanged=false;
	@Index
	protected Key<EmployeeRelation> keyName;

	/** Instantiates a new employee */
	public Employee()
	{
	    super();
		photo=new DocumentUpload();
		Contact temp=new Contact();
		contacts.add(temp);
		branchName="";
		designation="";
		roleName="";
		nameChanged=false;
		departMent="";
		reportsTo="";
		previousCompanyHistory=new ArrayList<PreviousCompanyHistory>();
		educationalInfo=new ArrayList<EducationalInfo>();
		information=new PassportInformation();
		employeeType="";
		country="";
		idCardNo="";
		accessCardNo="";
		
		employeeBankAccountNo="";
		
		employeeBankName="";
		
		 employeeESICcode="";
		
		employeePanNo="";
		
		
		
		ifscCode="";
		
		 bankBranch="";
		
		accountNo="";
		
		ppfNo="";
		bloodGroup="";
	}


	/**
	 * Gets the salary.
	 *
	 * @return the salary
	 */
	public Double getSalary() {
		return salary;
	}
	
	

	/**
	 * Sets the salary.
	 *
	 * @param salary the new salary
	 */


	/**
	 * Gets the joined at.
	 *
	 * @return the joined at
	 */
	
	public Date getJoinedAt() {
		return joinedAt;
	}
	
	public String getFullName()
	{
		return this.fullname;
	}

	/**
	 * Sets the joined at.
	 *
	 * @param joinedAt the new joined at
	 */
	public void setJoinedAt(Date joinedAt) {
		this.joinedAt = joinedAt;
	}
	/**
	 * Gets the photo.
	 *
	 * @return the photo
	 */
	public DocumentUpload getPhoto() {
		return photo;
	}
	
	public PassportInformation getPassPortInformation()
	{
		return this.information;
	}
	
	public void setPassPortInformation(PassportInformation information)
	{
		this.information=information;
	}

	/**
	 * Sets the photo.
	 *
	 * @param photo the new photo
	 */
	public void setPhoto(DocumentUpload photo) {
		this.photo = photo;
	}

	/**
	 * Checks if is status.
	 *
	 * @return true, if is status
	 */
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 6, isFieldUpdater = false, isSortable = true, 
			title = "Employee Status")
	public Boolean isStatus() {
		return status;
	}

	/**
	 * Sets the status.
	 *
	 * @param status the new status
	 */
	public void setStatus(boolean status) {
		this.status = status;
	}

	/**
	 * Gets the branch name.
	 *
	 * @return the branch name
	 */
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 3, isFieldUpdater = false, isSortable = true, 
			title = "Branch")
	public String getBranchName() {
		return branchName;
	}

	/**
	 * Sets the branch name.
	 *
	 * @param branchName the new branch name
	 */
	public void setBranchName(String branchName) {
		if(branchName!=null)
			this.branchName = branchName.trim();
	}

	/**
	 * Gets the designation.
	 *
	 * @return the designation
	 */
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 4, isFieldUpdater = false, isSortable = true,
			title = "Employee Designation")
	public String getDesignation() {
		return designation;
	}

	/**
	 * Sets the designation.
	 *
	 * @param designation the new designation
	 */
	public void setDesignation(String designation) {
		if(designation!=null)
			this.designation = designation.trim();
	}

	/**
	 * Gets the role name.
	 *
	 * @return the role name
	 */
	public String getRoleName() {
		return roleName;
	}

	/**
	 * Sets the role name.
	 *
	 * @param roleName the new role name
	 */
	public void setRoleName(String roleName) 
	{
		if(roleName!=null)
			this.roleName = roleName.trim();
	}

	public Long getLandline()
	{
		return this.contacts.get(0).getLandline();
	}

	public void setLandline(Long landline)
	{
		if(landline!=null)
			contacts.get(0).setLandline(landline);
		else
			contacts.get(0).setLandline(0l);
	}


	public void setEmail(String email)
	{
		if(email!=null)
			this.contacts.get(0).setEmail(email.trim());
	}

	public String getEmail()
	{
		return this.contacts.get(0).getEmail();
	}

	public Long getLandLine(Long landlineNo)
	{
		return this.contacts.get(0).getLandline();

	}

	public void setLandLine(Long landline)
	{
		if(landline!=null) 
			this.contacts.get(0).setLandline(landline);
	}

	public void setWebsite(String website)
	{
		this.contacts.get(0).setWebsite(website);
	}

	public String getWebsite()
	{
		return this.contacts.get(0).getWebsite();
	}

	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 2, isFieldUpdater = false, isSortable = true, 
			title = "Phone")
	public  Long getCellNumber1()
	{
		return contacts.get(0).getCellNo1();
	}

	public  void setCellNumber1(Long cellNuber1)
	{
		if(cellNuber1!=null)  
			contacts.get(0).setCellNo1(cellNuber1);
	}

	public  Long getCellNumber2()
	{
		return contacts.get(0).getCellNo2();
	}

	public  void setCellNumber2(Long cellNuber2)
	{
		if(cellNuber2!=null)  
			contacts.get(0).setCellNo2(cellNuber2);
	}

	public  long getFaxNumber()
	{
		return contacts.get(0).getFaxNo();
	}

	public  void setFaxNumber(Long faxno)
	{
		if(faxno!=null)    
			contacts.get(0).setFaxNo(faxno);
	}

	public void setAddress(Address address)
	{
		this.contacts.get(0).setAddress(address);
	}

	public Address getAddress()
	{
		return contacts.get(0).getAddress();
	}

	public void setSalary(Double salary) 
	{
		if(salary!=null)
			this.salary = salary;
		else
			this.salary=0;
	}
	

	
	

	@Override
	@TableAnnotation(ColType = FormTypes.TEXTCOLUM, colNo = 1, isFieldUpdater = false, isSortable = true, 
	title = "Name")
	public String getFullname() {
		// TODO Auto-generated method stub
		fillFullName();
		
		return super.getFullname();
	}

	@Override
	public void setFirstName(String firstName)
	{
		
		if(firstName==null)
			return;
		if(!(this.firstName.equals(firstName)))
			nameChanged=true;
		super.setFirstName(firstName);	
		
		
	}
	
	

	public String getIdCardNo() {
		return idCardNo;
	}

	public void setIdCardNo(String string) {
		this.idCardNo = string;
	}

	public String getAccessCardNo() {
		return accessCardNo;
	}

	public void setAccessCardNo(String string) {
		this.accessCardNo = string;
	}

	public String getDepartMent() {
		return departMent;
	}

	public void setDepartMent(String departMent) {
		this.departMent = departMent;
	}

	public String getReportsTo() {
		return reportsTo;
	}

	public void setReportsTo(String reportsTo) {
		this.reportsTo = reportsTo;
	}

	public ArrayList<String> getApprovers() {
		return approvers;
	}

	public void setApprovers(List<String> approvers) {
		if(approvers!=null)
		{
		this.approvers = new ArrayList<String>();
		this.approvers.addAll(approvers);
		
		}
	}

	public ArrayList<PreviousCompanyHistory> getPreviousCompanyHistory() {
		return previousCompanyHistory;
	}

	public void setPreviousCompanyHistory(
			List<PreviousCompanyHistory> list) {
		if(list!=null)
		{
		 previousCompanyHistory = new ArrayList<PreviousCompanyHistory>();
		 previousCompanyHistory.addAll(list);
		
		}
	}

	public ArrayList<EducationalInfo> getEducationalInfo() {
		return educationalInfo;
	}

	public void setEducationalInfo(List<EducationalInfo> list) {
		if(list!=null)
		{
		this.educationalInfo = new ArrayList<EducationalInfo>();
		educationalInfo.addAll(list);
		}
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	@Override
	public void setMiddleName(String middleName) 
	{
		if(middleName==null)
			return;
		if(!(this.middleName.equals(middleName)))
			nameChanged=true;
		super.setMiddleName(middleName);
		
	}

	@Override
	public void setLastName(String lastName) 
	{
		if(lastName==null)
		if(!(this.lastName.equals(lastName)))
			nameChanged=true;
		super.setLastName(lastName);
		
	}
	

public void setPreviousCompanyHistory(
			ArrayList<PreviousCompanyHistory> previousCompanyHistory) {
		this.previousCompanyHistory = previousCompanyHistory;
	}

	public void setEducationalInfo(ArrayList<EducationalInfo> educationalInfo) {
		this.educationalInfo = educationalInfo;
	}
	
	
	public String getEmployeeType() {
		return employeeType;
	}

	public void setEmployeeType(String employeeType) {
		if(employeeType!=null)
		this.employeeType = employeeType.trim();
	}






	

public PassportInformation getInformation() {
	return information;
}


public void setInformation(PassportInformation information) {
	this.information = information;
}


public String getIfscCode() {
	return ifscCode;
}


public void setIfscCode(String ifscCode) {
	if(ifscCode!=null)
	this.ifscCode = ifscCode;
}


public String getBankBranch() {
	return bankBranch;
}


public void setBankBranch(String bankBranch) {
	this.bankBranch = bankBranch;
}


public String getAccountNo() {
	return accountNo;
}


public void setAccountNo(String accountNo) {
	this.accountNo = accountNo;
}


public Key<Config> getKeyRole() {
	return keyRole;
}


public void setKeyRole(Key<Config> keyRole) {
	this.keyRole = keyRole;
}


public Key<Config> getKeyDesignation() {
	return keyDesignation;
}


public void setKeyDesignation(Key<Config> keyDesignation) {
	this.keyDesignation = keyDesignation;
}


public Key<BranchRelation> getKeyBranchName() {
	return keyBranchName;
}


public void setKeyBranchName(Key<BranchRelation> keyBranchName) {
	this.keyBranchName = keyBranchName;
}


public boolean isNameChanged() {
	return nameChanged;
}


public void setNameChanged(boolean nameChanged) {
	this.nameChanged = nameChanged;
}


public Key<EmployeeRelation> getKeyName() {
	return keyName;
}


public void setKeyName(Key<EmployeeRelation> keyName) {
	this.keyName = keyName;
}


public void setApprovers(ArrayList<String> approvers) {
	this.approvers = approvers;
}


/**************************************************Relation Managment Part******************************/
	@GwtIncompatible
	@OnSave
	public void onSave()
	{
		fillFullName();
		//Save New Relational Kind ,Entity is being saved for first time
		System.out.println("ID IS "+id);
		if(id==null)
		{
			//One Part Handling
			EmployeeRelation employeeRelation=new EmployeeRelation();
			employeeRelation.setEmployeeName(this.fullname);
		    
	/**************************************************One****************************************/		 
		}	 
			//Many Part Handling
			MyQuerry querry=new MyQuerry();
		  	Vector<Filter>filter=new Vector<Filter>();
		  	Filter nameFilter=new Filter();
		  	nameFilter.setStringValue(this.branchName);
		  	nameFilter.setQuerryString("branchName");
		  	filter.add(nameFilter);
		  	querry.setFilters(filter);
			
			querry.setQuerryObject(new BranchRelation());
			keyBranchName=(Key<BranchRelation>) MyUtility.getRelationalKeyFromCondition(querry);
			keyDesignation=MyUtility.getConfigKeyFromCondition(designation,ConfigTypes.
					EMPLOYEEDESIGNATION.getValue());
		    keyRole=MyUtility.getConfigKeyFromCondition(roleName,ConfigTypes.EMPLOYEEROLE.getValue());
		   
		
		
		{
			//Name has changed , this Relational Kind needs to be updated
			if(nameChanged==true)
			{
				System.out.println("Name Has Been Changed Value of Key Name is "+keyName);
				if(keyName!=null)
				{
				EmployeeRelation employeeRelation=new EmployeeRelation();
				employeeRelation.setEmployeeName(this.fullname);
				MyUtility.updateRelationalEntity(employeeRelation,keyName);
				}
				
			}
		}
	}

	@GwtIncompatible
	@OnLoad
	 public void onLoad()
	{
		this.fillAllNames();
		String branchName=MyUtility.getBranchNameFromKey(keyBranchName);
		if(branchName!=null)
		{
			if(branchName.equals("")==false)
				setBranchName(branchName.trim());
		}
		String roleName=MyUtility.getConfigNameFromKey(keyRole);
		if(roleName!=null)
		{
			if(roleName.equals("")==false)
				setRoleName(roleName.trim());
		}
		String designationName=MyUtility.getConfigNameFromKey(keyDesignation);
		if(designationName!=null)
		{
			if(designationName.equals("")==false)
				setDesignation(designationName.trim());
		}
		
		 
	}
/*****************************************************************************************************/

	@Override
	public String toString() {
		return fullname;
	}


public String getCountry() {
	return country;
}


public void setCountry(String country) {
	if(country!=null)
	this.country = country.trim();
}



@Override
public boolean equals(Object obj)
{
	if(obj==null)
		return false;
	else
	{
		if(obj instanceof Employee)
		{
			Employee emp=(Employee) obj;
			if(emp.getId()!=null&getId()!=null)
			{
				if(emp.getId()==getId())
					return true;
				else
					return false;
			}
			else
				return false;
			
			
		}
		return false;
	}
	
	
}


public void setPPFNumber(String value) {
	this.ppfNo=value.trim();
	
}


public String getPPFNaumber() {
	// TODO Auto-generated method stub
	return this.ppfNo;
}


public String getBloodGroup() {
	// TODO Auto-generated method stub
	return bloodGroup;
}


public void setBloodGroup(String value) {
	if(value!=null)
	this.bloodGroup=value.trim();
	
}



}
